#ifndef ACTOR_H
#define ACTOR_H

#include <glm.hpp>
#include <vector>
#include "Core/FRotator.h"

class Actor
{
public:
	using Super = Actor;

	Actor();
	virtual ~Actor();

	virtual void BeginPlay();
	virtual void Tick(double DetaTime);
	virtual void Destroyed();

	virtual void RenderActor();

	void SetActorLocation(glm::vec3 NewLocation);
	void SetActorAngle(float angle);
	void SetActorScale(glm::vec3 NewScale);
	void SetActorForward(glm::vec3 NewForward);
	void SetActorRotation(const FRotator& NewRotator);

	void SetupAttachment(Actor* AttachToParent);
	void UpdateChildLocation(glm::vec3 DetalLocation);
	void AddActorLocalRotation(const FRotator& DeltaRotation);

	void RecalculateTranformMatrix();
	glm::mat4 GetTransformMatrix();

	void SetRoot(Actor* root);
	void SetParent(Actor* parent);

	virtual void OnEvent(double DetaTime);
	virtual void OnMouse(double xoffset, double yoffset);

	virtual glm::vec3 GetForward2D();
	virtual glm::vec3 GetRight2D();
private:

	void AddToChildren(Actor* Child);

protected:
	glm::vec3 Location;

	FRotator Rotation;

	glm::vec3 RotationAxis;
	float Angle = 0.0f;
	glm::vec3 Scale;
	glm::vec3 Forward;
	glm::vec3 Right;
	glm::vec3 Up;
	glm::vec3 WorldUp;


	glm::vec3 Velocity;

	glm::vec3* Target;

	float MovementSpeed;

	std::vector<Actor*> Children;
	Actor* Parent;
	Actor* Root;


	glm::mat4 M;
	glm::mat4 T;
	glm::mat4 R;
	glm::mat4 S;

public:
	inline glm::vec3& GetActorLocation() { return Location; }
	inline glm::vec3 GetActorScale()const { return Scale; }
	inline FRotator GetActorRotation()const { return Rotation; }
	inline glm::vec3 GetActorForward()const { return Forward; }
	inline glm::vec3 GetVelocity() const { return Velocity; }
	inline Actor* GetRoot()const { return Root; };
	inline Actor* GetParent()const { return Parent; };
};

#endif